home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / program / mui32dev.lha / MUI / Developer / Modula / Demo / txt / Class2.mod next >
Text File  |  1995-11-06  |  12KB  |  415 lines

  1. MODULE Class2 ;
  2.  
  3. (* IMPORTANT: RangeChk mußt be switched off, otherwise you'll get an error
  4. ** when entering the Colorwheel-Page!
  5. *)
  6.  
  7. (*$ RangeChk := FALSE *)
  8.  
  9. FROM SYSTEM     IMPORT  TAG, ADR, ADDRESS, LONGSET, CAST, SETREG, REG ;
  10. FROM AmigaLib   IMPORT  DoSuperMethodA ;
  11. FROM ExecL      IMPORT  Wait ;
  12.  
  13. IMPORT
  14.         R,
  15.         gd  : GraphicsD,
  16.         gl  : GraphicsL,
  17.         id  : IntuitionD,
  18.         il  : IntuitionL,
  19.         m   : MuiD,
  20.         mc  : MuiClasses,
  21.         ml  : MuiL,
  22.         mm  : MuiMacros,
  23.         ms  : MuiSupport,
  24.         ud  : UtilityD,
  25.         ul  : UtilityL ;
  26.  
  27. (***************************************************************************)
  28. (* Here is the beginning of our simple new class...                        *)
  29. (***************************************************************************)
  30.  
  31. (*
  32. ** This class is the same as within Class1.c except that it features
  33. ** a pen attribute.
  34. *)
  35.  
  36. TYPE
  37.   LongcardPtr = POINTER TO LONGCARD ;
  38.  
  39.   Data = RECORD
  40.            penspec   : m.mPenSpec ;
  41.            pen       : ADDRESS;
  42.            penchange : BOOLEAN ;
  43.          END (* RECORD *) ;
  44.  
  45. CONST
  46.   MyAttrPen = LONGCARD(8022H) ; (* tag value for the new attribute.            *)
  47.  
  48. (*/// "mNew(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpSetPtr) : ADDRESS" *)
  49.  
  50. PROCEDURE mNew(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpSetPtr) : ADDRESS ;
  51.  
  52. VAR
  53.   data  : POINTER TO Data ;
  54.   tag,
  55.   tags  : ud.TagItemPtr ;
  56.  
  57. BEGIN
  58.   obj := DoSuperMethodA(cl, obj, msg) ;
  59.   IF obj = NIL THEN RETURN NIL END ;
  60.  
  61.   data := mc.InstData(cl, obj) ;
  62.  
  63.   (* parse initial taglist *)
  64.  
  65.   tags := msg^.attrList ;
  66.   tag  := ul.NextTagItem(tags) ;
  67.   WHILE tag # NIL DO
  68.     CASE tag^.tag OF
  69.     | MyAttrPen : IF tag^.data # 0 THEN
  70.                     data^.penspec := CAST(m.mPenSpecPtr, tag^.data)^ ;
  71.                   END (* IF *) ;
  72.     ELSE
  73.     END (* CASE *) ;
  74.     tag := ul.NextTagItem(tags) ;
  75.   END (* WHILE *) ;
  76.  
  77.   RETURN obj ;
  78. END mNew ;
  79.  
  80. (*\\\*)
  81. (*/// "mDispose(cl : id.IClassPtr; obj : id.ObjectPtr; msg : ADDRESS) : ADDRESS" *)
  82.  
  83. PROCEDURE mDispose(cl : id.IClassPtr; obj : id.ObjectPtr; msg : ADDRESS) : ADDRESS ;
  84.  
  85. BEGIN
  86.   (* OM_NEW didnt allocates something, just do nothing here... *)
  87.   RETURN DoSuperMethodA(cl, obj, msg) ;
  88. END mDispose ;
  89.  
  90. (*\\\*)
  91.  
  92. (*
  93. ** OM_SET method, we need to see if someone changed the penspec attribute.
  94. *)
  95.  
  96. (*/// "mSet(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpSetPtr) : ADDRESS" *)
  97.  
  98. PROCEDURE mSet(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpSetPtr) : ADDRESS ;
  99.  
  100. VAR
  101.   data : POINTER TO Data ;
  102.   tag,
  103.   tags : ud.TagItemPtr ;
  104.  
  105. BEGIN
  106.   data := mc.InstData(cl, obj) ;
  107.  
  108.   tags := msg^.attrList ;
  109.   tag  := ul.NextTagItem(tags) ;
  110.   WHILE tag # NIL DO
  111.     CASE tag^.tag OF
  112.     | MyAttrPen : IF tag^.data # 0 THEN
  113.                     data^.penspec   := CAST(m.mPenSpecPtr, tag^.data)^ ;
  114.                     data^.penchange := TRUE ;
  115.                     IF ml.moRedraw(obj, CAST(LONGCARD, mc.MADFlagSet{mc.drawObject})) # NIL THEN END ;
  116.                   END (* IF *) ;
  117.     ELSE
  118.     END (* CASE *) ;
  119.     tag := ul.NextTagItem(tags) ;
  120.   END (* WHILE *) ;
  121.  
  122.   RETURN DoSuperMethodA(cl, obj, msg) ;
  123. END mSet ;
  124.  
  125. (*\\\*)
  126.  
  127. (*
  128. ** OM_GET method, see if someone wants to read the color.
  129. *)
  130.  
  131. (*/// "mGet(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpGetPtr) : ADDRES" *)
  132.  
  133. PROCEDURE mGet(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpGetPtr) : ADDRESS;
  134.  
  135. VAR
  136.   data  : POINTER TO Data ;
  137.   store : LongcardPtr ;
  138.  
  139. BEGIN
  140.   data := mc.InstData(cl, obj) ;
  141.   store := CAST(LongcardPtr, msg^.storage) ;
  142.  
  143.   CASE msg^.attrID OF
  144.   | MyAttrPen : store^ := ADR(data^.penspec) ;
  145.                 RETURN LONGCARD(TRUE) ;
  146.   ELSE
  147.     RETURN DoSuperMethodA(cl, obj, msg) ;
  148.   END (* CASE *) ;
  149. END mGet ;
  150.  
  151. (*\\\*)
  152. (*/// "mSetup(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpSetPtr) : ADDRES" *)
  153.  
  154. PROCEDURE mSetup(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpSetPtr) : ADDRESS;
  155.  
  156. VAR
  157.   data : POINTER TO Data ;
  158.   test : ADDRESS ;
  159.  
  160. BEGIN
  161.   data := mc.InstData(cl, obj) ;
  162.  
  163.   IF DoSuperMethodA(cl, obj, msg) = NIL THEN
  164.     RETURN LONGCARD(FALSE) ;
  165.   END (* IF *) ;
  166.  
  167.   test := mc.muiRenderInfo(obj) ;
  168.   data^.pen := ml.moObtainPen(mc.muiRenderInfo(obj), ADR(data^.penspec)) ;
  169.  
  170.   RETURN LONGCARD(TRUE) ;
  171. END mSetup ;     
  172.  
  173. (*\\\*)
  174. (*/// "mCleanup(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpSetPtr) : ADDRES" *)
  175.  
  176. PROCEDURE mCleanup(cl : id.IClassPtr; obj : id.ObjectPtr; msg : id.OpSetPtr) : ADDRESS;
  177.  
  178. VAR
  179.   data :POINTER TO Data ;
  180.  
  181. BEGIN
  182.   data := mc.InstData(cl, obj) ;
  183.   ml.moReleasePen(mc.muiRenderInfo(obj), data^.pen) ;
  184.   RETURN DoSuperMethodA(cl, obj, msg) ;
  185. END mCleanup ;
  186.  
  187. (*\\\*)
  188. (*/// "mAskMinMax(cl : id.IClassPtr; obj : id.ObjectPtr; msg : mc.mpAskMinMaxPtr) : ADDRES" *)
  189.  
  190. PROCEDURE mAskMinMax(cl : id.IClassPtr; obj : id.ObjectPtr; msg : mc.mpAskMinMaxPtr) : ADDRESS;
  191.  
  192. BEGIN
  193.   (*
  194.   ** let our superclass first fill in what it thinks about sizes.
  195.   ** this will e.g. add the size of frame and inner spacing.
  196.   *)
  197.  
  198.   IF DoSuperMethodA(cl, obj, msg) # NIL THEN END ;
  199.  
  200.   (*
  201.   ** now add the values specific to our object. note that we
  202.   ** indeed need to *add* these values, not just set them!
  203.   *)
  204.  
  205.   INC(msg^.MinMaxInfo^.MinWidth, 100) ;
  206.   INC(msg^.MinMaxInfo^.DefWidth, 120) ;
  207.   INC(msg^.MinMaxInfo^.MaxWidth, 500) ;
  208.  
  209.   INC(msg^.MinMaxInfo^.MinHeight, 40) ;
  210.   INC(msg^.MinMaxInfo^.DefHeight, 90) ;
  211.   INC(msg^.MinMaxInfo^.MaxHeight, 300) ;
  212.  
  213.   RETURN NIL ;
  214. END mAskMinMax ;
  215.  
  216. (*\\\*)
  217.  
  218. (*
  219. ** Draw method is called whenever MUI feels we should render
  220. ** our object. This usually happens after layout is finished
  221. ** or when we need to refresh in a simplerefresh window.
  222. ** Note: You may only render within the rectangle
  223. **       _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj).
  224. *)
  225.  
  226. (*/// "mDraw(cl : id.IClassPtr; obj : id.ObjectPtr; msg : mc.mpDraw) : ADDRES" *)
  227.  
  228. PROCEDURE mDraw(cl : id.IClassPtr; obj : id.ObjectPtr; msg : mc.mpDrawPtr) : ADDRESS;
  229.  
  230. VAR
  231.   data : POINTER TO Data ;
  232.   i    : INTEGER ;
  233.  
  234. BEGIN
  235.   data := mc.InstData(cl, obj) ;
  236.  
  237.   (*
  238.   ** let our superclass draw itself first, area class would
  239.   ** e.g. draw the frame and clear the whole region. What
  240.   ** it does exactly depends on msg->flags.
  241.   *)
  242.  
  243.   IF DoSuperMethodA(cl, obj, msg) # NIL THEN END ;
  244.  
  245.   (*
  246.   ** if MADF_DRAWOBJECT isn't set, we shouldn't draw anything.
  247.   ** MUI just wanted to update the frame or something like that.
  248.   *)
  249.  
  250.   IF NOT (mc.drawObject IN msg^.flags) THEN RETURN NIL END ;
  251.  
  252.   (*
  253.   ** test if someone changed our pen
  254.   *)
  255.  
  256.   IF data^.penchange THEN
  257.     data^.penchange := FALSE ;
  258.     ml.moReleasePen(mc.muiRenderInfo(obj), data^.pen) ;
  259.     data^.pen := ml.moObtainPen(mc.muiRenderInfo(obj), ADR(data^.penspec)) ;
  260.   END (* IF *) ;
  261.  
  262.   (*
  263.   ** ok, everything ready to render...
  264.   ** Note that we *must* use the MUIPEN() macro before actually
  265.   ** using pens from MUI_ObtainPen() in rendering calls.
  266.   *)
  267.  
  268.   gl.SetAPen(mc.OBJ_rp(obj),mc.muiPen(data^.pen));
  269.  
  270.   FOR i := mc.OBJ_mleft(obj) TO mc.OBJ_mright(obj) BY 5 DO
  271.     gl.Move(mc.OBJ_rp(obj),mc.OBJ_mleft(obj),mc.OBJ_mtop(obj));
  272.     gl.Draw(mc.OBJ_rp(obj),i,mc.OBJ_mbottom(obj));
  273.     gl.Move(mc.OBJ_rp(obj),mc.OBJ_mright(obj),mc.OBJ_mtop(obj));
  274.     gl.Draw(mc.OBJ_rp(obj),i,mc.OBJ_mbottom(obj));
  275.   END (* FOR *) ;
  276.  
  277.   RETURN NIL ;
  278. END mDraw ;
  279.  
  280. (*\\\*)
  281.  
  282. (*
  283. ** Here comes the dispatcher for our custom class. We only need to
  284. ** care about MUIM_AskMinMax and MUIM_Draw in this simple case.
  285. ** Unknown/unused methods are passed to the superclass immediately.
  286. *)
  287.  
  288. (*/// "MyDispatcher(cl : id.IClassPtr; obj : ADDRESS; msg : ADDRESS) : ADDRESS" *)
  289.  
  290. PROCEDURE MyDispatcher(cl : id.IClassPtr; obj : ADDRESS; msg : ADDRESS) : ADDRESS ;
  291.  
  292. VAR
  293.   mid : LONGCARD ;
  294.  
  295. BEGIN
  296.   mid := CAST(id.Msg, msg)^.methodID ;
  297.  
  298.      IF mid = id.omNEW      THEN RETURN mNew(cl, obj, msg)
  299.   ELSIF mid = id.omDISPOSE  THEN RETURN mDispose(cl, obj, msg)
  300.   ELSIF mid = id.omSET      THEN RETURN mSet(cl, obj, msg)
  301.   ELSIF mid = id.omGET      THEN RETURN mGet(cl, obj, msg)
  302.   ELSIF mid = m.mmAskMinMax THEN RETURN mAskMinMax(cl, obj, msg)
  303.   ELSIF mid = m.mmSetup     THEN RETURN mSetup(cl, obj, msg)
  304.   ELSIF mid = m.mmCleanup   THEN RETURN mCleanup(cl, obj, msg)
  305.   ELSIF mid = m.mmDraw      THEN RETURN mDraw(cl, obj, msg)
  306.   ELSE
  307.     RETURN DoSuperMethodA(cl, obj, msg)
  308.   END (* CASE *) ;
  309. END MyDispatcher ;
  310.  
  311. (*\\\*)
  312.  
  313. (***************************************************************************)
  314. (* Thats all there is about it. Now lets see how things are used...        *)
  315. (***************************************************************************)
  316.  
  317. VAR
  318.   app,
  319.   window,
  320.   grp,
  321.   myObj,
  322.   pen      : id.ObjectPtr ;
  323.   mcc      : mc.mCustomClassPtr ;
  324.   signals  : LONGSET ;
  325.   running  := BOOLEAN{TRUE} ;
  326.   startpen : m.mPenSpecPtr ;
  327.   NULL     :=ADDRESS{NIL};
  328.  
  329.   tags     : ARRAY [0..31] OF LONGINT ;
  330.  
  331. BEGIN
  332.   (* Create the new custom class with a call to MUI_CreateCustomClass(). *)
  333.   (* Caution: This function returns not a struct IClass, but a           *)
  334.   (* struct MUI_CustomClass which contains a struct IClass to be         *)
  335.   (* used with NewObject() calls.                                        *)
  336.   (* Note well: MUI creates the dispatcher hook for you, you may         *)
  337.   (* *not* use its h_Data field! If you need custom data, use the        *)
  338.   (* cl_UserData of the IClass structure!                                *)
  339.  
  340.   IF ml.muiMasterVersion < 11 THEN ms.fail(NULL, "You need MUI 3 to run this demo.") END;
  341.  
  342.   mcc := ml.moCreateCustomClass(NIL, ADR(m.mcArea), NIL, SIZE(Data), ADR(MyDispatcher)) ;
  343.   IF mcc = NIL THEN ms.fail(NULL, "Could not create custom class.") END ;
  344.  
  345.   mc.MakeDispatcher(MyDispatcher, mcc^.class) ;
  346.  
  347.   pen := mm.PenadjustObject(TAG(tags, m.maPenadjustDoSyspens, FALSE, ud.tagDone));
  348.   myObj := il.NewObjectA(mcc^.class, NIL, TAG(tags, m.maFrame,      m.mvFrameText,
  349.                                                     m.maBackground, m.miBACKGROUND,
  350.                                               ud.tagDone)) ;
  351.  
  352.   grp := mm.GroupObject(TAG(tags, m.maGroupHoriz,  TRUE,
  353.                                   mm.Child,        myObj,
  354.                                   mm.Child,        pen,
  355.                             ud.tagDone)) ;
  356.  
  357.   window := mm.WindowObject(TAG(tags, m.maWindowTitle, ADR("Another Custom Class"),
  358.                                       m.maWindowID,    mm.MakeID("CLS2"),
  359.                                       mm.WindowContents, grp,
  360.                                 ud.tagDone)) ;
  361.  
  362.   app := mm.ApplicationObject(TAG(tags, m.maApplicationTitle,       ADR("Class2-M2"),
  363.                                         m.maApplicationVersion,     ADR("$VER: Class2-M2 11.1 (21.9.95)"),
  364.                                         m.maApplicationCopyright,   ADR("©1995, Olaf Peters, Stefan Stuntz"),
  365.                                         m.maApplicationAuthor,      ADR("Olaf Peters, Stefan Stuntz"),
  366.                                         m.maApplicationDescription, ADR("Demonstrate the use of custom classes."),
  367.                                         m.maApplicationBase,        ADR("CLASS2M2"),
  368.                                         mm.SubWindow,               window,
  369.                                   ud.tagDone)) ;
  370.  
  371.   IF app = NIL THEN ms.fail(NULL, "Failed to create Application.") END ;
  372.  
  373.   mm.NoteClose(app, window, m.mvApplicationReturnIDQuit) ;
  374.  
  375.   ms.DoMethod(pen,TAG(tags, m.mmNotify, m.maPenadjustSpec, m.mvEveryTime,
  376.                          myObj, 3, m.mmSet, MyAttrPen, m.mvTriggerValue,
  377.                    ud.tagDone));
  378.  
  379.   mm.get(pen, m.maPenadjustSpec, ADR(startpen)) ;
  380.   mm.set(myObj, MyAttrPen, LONGCARD(startpen)) ;
  381.  
  382. (*
  383. ** Input loop...
  384. *)
  385.  
  386.   mm.set(window, m.maWindowOpen, LONGCARD(TRUE)) ;
  387.  
  388.   WHILE running DO
  389.     CASE ms.DOMethod(app, TAG(tags, m.mmApplicationInput, ADR(signals), ud.tagDone)) OF
  390.     | m.mvApplicationReturnIDQuit : running := FALSE ;
  391.     ELSE
  392.     END (* CASE *) ;
  393.     IF running AND (signals # LONGSET{}) THEN
  394.       signals := Wait(signals) ;
  395.     END (* IF *) ;
  396.   END (* WHILE *) ;
  397.  
  398.   mm.set(window, m.maWindowOpen, LONGCARD(FALSE)) ;
  399.  
  400. (*
  401. ** Shut down...
  402. *)
  403.  
  404. CLOSE
  405.   IF app # NIL THEN
  406.     ml.mDisposeObject(app)
  407.     app := NIL ;
  408.   END (* IF *) ;
  409.  
  410.   IF mcc # NIL THEN
  411.     IF ml.moDeleteCustomClass(mcc) THEN END ;
  412.     mcc := NIL ;
  413.   END (* IF *) ;
  414. END Class2.
  415.